<template>
  <el-dialog
    append-to-body
    :before-close="beforeClose"
    fullscreen
    :title="title"
    :visible.sync="dialogVisible"
    width="1600px"
    @close="close"
  >
    <template slot="title">
      <div>
        <span class="font16 mr12">{{ title }}</span>
        <el-select
          v-model="bloodSource"
          class="wd200 mr12"
          clearable
          filterable
          placeholder="血源"
        >
          <el-option
            v-for="(item, index) in bloodSources"
            :key="index"
            item.id
            :label="item.name"
            :value="item.id"
          />
        </el-select>
        <el-button
          v-if="formDatas.length > 0"
          class="ml12"
          icon="el-icon-document"
          type="primary"
          @click="submit"
        >
          提交
        </el-button>
      </div>
    </template>
    <div class="ele-table-tool-default d-flex align-items-center">
      <div>
        <span class="wd100">血袋号长度：</span>
        <el-input
          v-model="bloodCodeLength"
          class="wd200"
          clearable
          placeholder="血袋号长度"
          size="mini"
          type="number"
        />
      </div>
      <div class="ml12">
        <span class="wd100">增加行数：</span>
        <el-input
          v-model="addRows"
          class="wd200"
          clearable
          placeholder="增加行数"
          size="mini"
          type="number"
          @blur="handleAddRows"
        />
      </div>
      <div class="mlauto" style="margin-left: auto">
        <el-checkbox v-model="copyable" :false-label="0" :true-label="1">
          继承
        </el-checkbox>
      </div>
    </div>
    <el-table
      border
      :data="formDatas"
      :row-class-name="tableRowClassName"
      stripe
      style="width: 100%"
      @row-click="setIndex"
    >
      <el-table-column align="center" label="operate" prop="操作" width="100">
        <template #header>
          <el-link type="primary" @click="addRow">增加</el-link>
        </template>
        <template #default="{ $index }">
          <el-link type="danger" @click="deleteRow($index)">删除</el-link>
        </template>
      </el-table-column>
      <el-table-column align="center" label="序号" type="index" width="80" />
      <el-table-column align="center" label="血袋号" prop="id_out" width="200">
        <template slot-scope="scope">
          <el-input
            :ref="`input${scope.$index * 4 + 1}`"
            v-model.trim="scope.row.id_out"
            clearable
            placeholder="原始血袋号"
            size="mini"
            @input="
              handleChange(
                scope.row,
                `input${scope.$index * 4 + 2}`,
                scope.$index
              )
            "
          />
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="血型码"
        prop="abo_code"
        width="120"
      >
        <template slot-scope="scope">
          <el-input
            :ref="`input${scope.$index * 4 + 2}`"
            v-model.trim="scope.row.abo_code"
            clearable
            placeholder="血型码"
            size="mini"
            @input="
              parseBloodGroupRhdByCode(
                scope.row,
                `input${scope.$index * 4 + 3}`,
                scope.$index
              )
            "
          />
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="血液成分码"
        prop="product_code"
        width="150"
      >
        <template slot-scope="scope">
          <el-input
            :ref="`input${scope.$index * 4 + 3}`"
            v-model.trim="scope.row.product_code"
            clearable
            placeholder="血液成分码"
            size="mini"
            @input="
              parseBloodComponentByCode(
                scope.row,
                `input${scope.$index * 4 + 4}`,
                scope.$index
              )
            "
          />
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="失效日期码"
        prop="invalid_time_code"
        width="150"
      >
        <template slot-scope="scope">
          <el-input
            :ref="`input${scope.$index * 4 + 4}`"
            v-model.trim="scope.row.invalid_time_code"
            clearable
            placeholder="失效日期码"
            size="mini"
            @input="
              parseBloodInvalidTimeByCode(
                scope.row,
                `input${scope.$index * 4 + 5}`,
                scope.$index
              )
            "
          />
        </template>
      </el-table-column>
      <el-table-column align="center" label="血型" prop="abo" width="100">
        <template slot-scope="scope">
          <el-select
            v-model="scope.row.abo"
            clearable
            filterable
            placeholder="请选择"
            size="mini"
          >
            <el-option
              v-for="(item, index) in bloodGroups.slice(0, 4)"
              :key="index"
              :label="item"
              :value="item"
            />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column align="center" label="RHD" prop="rhd" width="100">
        <template slot-scope="scope">
          <el-select
            v-model="scope.row.rhd"
            clearable
            filterable
            placeholder="请选择"
            size="mini"
          >
            <el-option
              v-for="(item, index) in bloodRhds"
              :key="index"
              :label="item"
              :value="item"
            />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="血液成分"
        prop="product_id_path"
        width="200"
      >
        <template slot-scope="scope">
          <el-cascader
            v-model="scope.row.product_id_path"
            :options="products"
            :props="props"
            :show-all-levels="false"
            @change="selectBloodComponent(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column align="center" label="血量" prop="capacity" width="120">
        <template slot-scope="scope">
          <el-input-number
            v-model="scope.row.capacity"
            :max="4"
            :min="0.5"
            placeholder="血量"
            size="mini"
            style="width: 100px"
          />
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="采血时间"
        prop="collect_time"
        width="202"
      >
        <template slot-scope="scope">
          <el-date-picker
            v-model="scope.row.collect_time"
            placeholder="选择时间"
            size="mini"
            type="datetime"
            value-format="yyyy-MM-dd HH:mm:ss"
          />
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="失效时间"
        prop="invalid_time"
        width="202"
      >
        <template slot-scope="scope">
          <el-date-picker
            v-model="scope.row.invalid_time"
            placeholder="失效时间"
            size="mini"
            type="datetime"
            value-format="yyyy-MM-dd HH:mm:ss"
            @change="selectInvalidTime(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="血袋位置"
        prop="position"
        width="150"
      >
        <template slot-scope="scope">
          <el-input
            v-model="scope.row.position"
            clearable
            placeholder="血袋位置"
            size="mini"
          />
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>
</template>
<script>
  import {
    getNextTime,
    parseBloodGroupRhdByCode,
    parseBloodComponentByCode,
    parseBloodInvalidTimeByCode,
    convertArr2Obj,
    deepClone,
  } from '@/utils'
  import {
    bloodGroups,
    bloodGroupRhdCodelength,
    bloodInvalidTimeCodeLength,
  } from '@/utils/constant'
  import { mapGetters } from 'vuex'
  import { getAll } from '@/api/bloodSource'
  export default {
    name: 'MainFormMulti',
    data() {
      return {
        copyable: true,
        dialogVisible: false,
        title: '外买血液接收',
        props: { label: 'name', value: 'id' },
        formDatas: [
          {
            id_out: '',
            product_id_path: '',
            abo: '',
            rhd: '阳性',
            capacity: 1,
            collect_time: '',
            invalid_time: '',
            blood_user: '',
            abo_code: '',
            product_code: '',
            invalid_time_code: '',
          },
        ],
        bloodGroups: bloodGroups,
        bloodRhds: ['阳性', '阴性'],
        tableData: [],
        count: 0,
        capacity: 0,
        currentIndex: 0,
        bloodSource: '',
        bloodSources: [],
        bloodCodeLength: 16,
        lastAction: 'add',
        addRows: '',
      }
    },
    computed: {
      ...mapGetters(['products', 'systemSet']),
      productsAll() {
        let res = []
        this.products.forEach((item) => {
          res = res.concat(item.children)
        })
        return res
      },
      productsAllObj() {
        return convertArr2Obj(this.productsAll, 'id')
      },
      bloodTimoutS() {
        return 500
      },
      bloodTimoutL() {
        return 3000
      },
    },
    watch: {
      formDatas: {
        handler(newVal) {
          if (newVal.length > 0) {
            const {
              abo,
              rhd,
              id_out,
              product_id_path,
              collect_time,
              invalid_time,
            } = newVal[newVal.length - 1]
            if (
              abo &&
              rhd &&
              id_out &&
              id_out.length === +this.bloodCodeLength &&
              product_id_path &&
              product_id_path.length === 2 &&
              collect_time &&
              invalid_time &&
              this.lastAction === 'add'
            ) {
              this.addRow()
            }
          }
        },
        deep: true,
        immediate: true,
      },
    },
    mounted() {
      this.enterKeyup()
      this.$nextTick(() => {
        if (this.$refs.input1) {
          this.$refs.input1.focus()
        }
      })
      this.bloodCodeLength = this.systemSet.blood_serialno_length || 16
    },
    methods: {
      handleAddRows() {
        for (let i = 0; i < this.addRows; i++) {
          this.formDatas.push({
            id_out: '',
            product_id_path: '',
            abo: '',
            rhd: '阳性',
            capacity: 1,
            collect_time: '',
            invalid_time: '',
            blood_user: '',
            abo_code: '',
            product_code: '',
            invalid_time_code: '',
          })
        }
      },
      async getAll() {
        const {
          data: { data },
        } = await getAll({ pagesize: 100, order: 'idx asc' })
        this.bloodSources = data.filter((val) => {
          return (
            val.name.indexOf('自采') === -1 && val.name.indexOf('自体') === -1
          )
        })
      },
      beforeClose() {
        if (this.formDatas.length > 0) {
          this.$baseConfirm(
            '确定要退出当前界面吗？此操作会清空已录入记录',
            null,
            async () => {
              this.dialogVisible = false
            }
          )
        } else {
          this.dialogVisible = false
        }
      },
      close() {
        this.formDatas = [
          {
            id_out: '',
            product_id_path: '',
            abo: '',
            rhd: '阳性',
            capacity: 1,
            collect_time: '',
            invalid_time: '',
            blood_user: '',
            abo_code: '',
            product_code: '',
            invalid_time_code: '',
          },
        ]
      },
      show() {
        this.getAll()
        this.dialogVisible = true
      },
      switchTab(ref, index) {
        this.currentIndex = index
        if (this.$refs[ref]) {
          this.$refs[ref].focus()
        }
      },
      parseBloodGroupRhdByCode(row, ref, index) {
        let abo_code = row.abo_code || ''
        const pattern = /\w+/
        const result = abo_code.match(pattern)
        if (result) {
          abo_code = result[0]
          row.abo_code = abo_code
          if (abo_code.length === bloodGroupRhdCodelength) {
            const blood = parseBloodGroupRhdByCode(abo_code)
            row.abo = blood.abo
            row.rhd = blood.rhd
            setTimeout(() => {
              this.switchTab(ref, index)
            }, 300)
          }
        }
      },
      parseBloodComponentByCode(row, ref, index) {
        let product_code = row.product_code || ''
        const pattern = /\w+/
        const result = product_code.match(pattern)
        if (result) {
          product_code = result[0]
          row.product_code = product_code
          const res = parseBloodComponentByCode(product_code, this.products)
          const product = this.productsAllObj[res[1]] || {}
          if (product) {
            row.capacity = product.capacity_init || 1
          }
          if (res.length === 2) {
            row.product_id_path = res
            row.product_id = res[1]
            setTimeout(() => {
              this.switchTab(ref, index)
            }, 300)
          } else {
            row.product_id_path = ''
            row.product_id = ''
          }
        }
      },
      parseBloodInvalidTimeByCode(row, ref, index) {
        let invalid_time_code = row.invalid_time_code || ''
        const pattern = /\w+/
        const result = invalid_time_code.match(pattern)
        if (result) {
          invalid_time_code = result[0]
          row.invalid_time_code = invalid_time_code
          setTimeout(() => {
            const res = parseBloodInvalidTimeByCode(invalid_time_code)
            console.log(res)
            row.invalid_time = res
            if (
              row.product_id_path &&
              row.product_id_path.length > 0 &&
              invalid_time_code.length >= bloodInvalidTimeCodeLength
            ) {
              const valid_days = this.getValidDays(row)
              row.collect_time = getNextTime(res, valid_days * -1)
              this.addRow()
              setTimeout(() => {
                this.switchTab(ref, index)
              }, 300)
            }
          }, 600)
        }
      },
      addRow() {
        if (this.copyable && this.formDatas.length > 0) {
          const rows = this.formDatas.filter((val) => {
            return val.abo
          })
          let formDataLastRow = deepClone(this.formDatas[rows.length - 1])
          formDataLastRow.id_out = ''
          formDataLastRow.tube_number = ''
          formDataLastRow.position = ''
          this.formDatas.push(formDataLastRow)
        } else {
          this.formDatas.push({
            id_out: '',
            product_id_path: '',
            abo: '',
            rhd: '阳性',
            capacity: 1,
            collect_time: '',
            invalid_time: '',
            blood_user: '',
            abo_code: '',
            product_code: '',
            invalid_time_code: '',
          })
        }
        this.currentIndex += 1
        const index = this.currentIndex
        setTimeout(() => {
          const ref = `input${index * 4 + 1}`
          this.switchTab(ref, index)
        }, 500)
      },
      deleteRow(index) {
        if (index === this.formDatas.length - 1) {
          this.lastAction = 'delete'
        }
        this.formDatas.splice(index, 1)
      },
      submit() {
        if (!this.bloodSource) {
          this.$baseMessage('请选择血源', 'error', 'vab-hey-message-error')
          return
        }
        let formDatas = this.formDatas.filter((val) => {
          return (
            val.id_out &&
            val.abo &&
            val.rhd &&
            val.capacity &&
            val.product_id_path &&
            val.collect_time &&
            val.invalid_time
          )
        })
        if (formDatas.length === 0) {
          this.$baseMessage(
            '提交记录中无属性完全的血液信息，请核查',
            'error',
            'vab-hey-message-error'
          )
          return
        }
        formDatas.map((val) => {
          val.from = this.bloodSource
          return val
        })
        this.$confirm('确定要提交吗？请先核对信息是否正确', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        })
          .then(() => {
            this.$emit('submit', formDatas)
          })
          .catch(() => {
            console.log('cancel')
          })
      },
      clear() {
        this.formDatas = []
        this.dialogVisible = false
      },
      selectInvalidTime(row) {
        const valid_days = this.getValidDays(row)
        row.collect_time = getNextTime(row.invalid_time, valid_days * -1)
      },
      handleChange(row, ref, index) {
        index = index * 4 + 1
        const {
          abo,
          rhd,
          id_out,
          product_id_path,
          collect_time,
          invalid_time,
        } = this.formDatas[this.formDatas.length - 1]
        if (
          Math.ceil(index / 4) === this.formDatas.length &&
          !(
            abo &&
            rhd &&
            id_out &&
            id_out.length === +this.bloodCodeLength &&
            product_id_path &&
            product_id_path.length === 2 &&
            collect_time &&
            invalid_time
          )
        ) {
          if (id_out.length === +this.bloodCodeLength) {
            setTimeout(() => {
              this.switchTab(ref, index)
            }, 300)
          }
        }
      },
      selectBloodComponent(row) {
        const res = row.product_id_path
        const product = this.productsAllObj[res[1]] || {}
        if (product) {
          row.capacity = product.capacity_init || 1
        }
      },
      getValidDays(row) {
        let valid_days = 30
        if (row.product_id_path) {
          const product = this.productsAllObj[row.product_id_path[1]]
          valid_days = product.valid_days
        }
        return valid_days
      },
      tableRowClassName({ row, rowIndex }) {
        row.index = rowIndex
      },
      setIndex(row) {
        this.currentIndex = row.index
      },
      enterKeyup() {
        document.addEventListener('keyup', this.enterKey)
      },
      enterKey(event) {
        const code = event.keyCode
          ? event.keyCode
          : event.which
          ? event.which
          : event.charCode

        if (code === 13) {
          const index = this.currentIndex + 1
          this.currentIndex = index
          const ref = `input${4 * index + 1}`
          if (this.$refs[ref]) {
            this.$refs[ref].focus()
          }
        }
      },
    },
  }
</script>

<style lang="scss" scoped>
  .action-items {
    padding: 12px;
    background: #fafafa;
    border: 1px solid #f0f0f0;
    border-top: none;
  }
</style>
